#ifndef __ENGINE_RESPONSE_included
#define __ENGINE_RESPONSE_included

#include "package.h"

namespace Engine {

#define RESPONSE_STATUS_OK 200
#define RESPONSE_STATUS_BadRequest 400
#define RESPONSE_STATUS_Unauthozied 401
#define RESPONSE_STATUS_Forbidden 403
#define RESPONSE_STATUS_FileNotFound 404
#define RESPONSE_STATUS_SessionNotFound 480

#define AUTH_TYPE_DIGEST	"Digest"
#define AUTH_ALGORITHN_MD5	"MD5"
#define AUTH_INFO_TYPE		"type"
#define AUTH_INFO_REALM		"realm"
#define AUTH_INFO_NONCE		"nonce"
#define AUTH_INFO_OPAQUE	"opaque"
#define AUTH_INFO_URI		"uri"
#define AUTH_INFO_USERRNAME	"username"
#define AUTH_INFO_RESP		"response"
#define AUTH_INFO_ALGORITHM	"algorithm"

class CDevice;

class CRequest;

class CResponse : public CPackage
{
	int mStatus;
	string mStatusDesc;
	std::map<string, string> mAuthInfo;

protected :
	virtual void ParseHead(string &line);
	void ParseAuthInfo(string& value);
	void PostParse();

public :

	CResponse(void);
	CResponse(string& head, boost::asio::streambuf& data);
	CResponse(string& head, boost::shared_ptr<std::istream> is);
#ifdef SERVER
	CResponse(boost::shared_ptr<CDevice> dev);
#endif

	virtual ~CResponse(void);

	bool HasAuthorization() { return mAuthInfo.size() > 0; }
	int GetStatus() { return mStatus; }
	void SetStatus(int s);
	string& GetStatusDesc() { return mStatusDesc; }

	string& GetAuthParameter(string& name) {
		map<string, string>::iterator i = mAuthInfo.find(name);
		if(i != mAuthInfo.end()) return i->second;
		else return CPackage::NULL_STRING;
	}

	bool MatchRequest(boost::shared_ptr<CRequest> r);

	virtual void GetData(ostream& os);
	virtual bool IsRequest() { return false; }

};

typedef boost::shared_ptr<CResponse> ResponseRef;

}

#endif // __ENGINE_RESPONSE_included